package org.twdata.pipeline.stage;

import java.io.StringWriter;
import java.io.Writer;
import javax.xml.transform.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.sax.*;
import javax.xml.transform.stream.*;

import org.twdata.pipeline.*;
import org.w3c.dom.*;

// SAX imports:
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.ext.LexicalHandler;

/**  Generates SAX events from a DOM node.  */
public class DOMGenerator implements Generator {

    private TransformerFactory tfactory;
    private javax.xml.transform.Transformer transformer = null;
    private Node input;
    private XMLConsumer consumer;
    private String id;


    /**
     *  Initializes the generator for the current context
     *
     *@param  ctx                    The context information
     *@exception  PipelineException  If anything goes wrong
     */
    public void setup(PipelineContext ctx)
        throws PipelineException {
        try {
            if (tfactory == null) {
                tfactory = TransformerFactory.newInstance();
                tfactory.setErrorListener(new TraxErrorListener());
            }
            transformer = tfactory.newTransformer();
        } catch (Exception ex) {
            throw new PipelineException(ex);
        }
        Source src = ctx.getSource();
        if (src instanceof DOMSource) {
            input = ((DOMSource)src).getNode();
        } else {
            throw new PipelineException("Source type not supported");
        }
    }


    /**
     *  Sets the consumer to publish XML SAX events to
     *
     *@param  consumer               The new consumer
     *@exception  PipelineException  If anything goes wrong
     */
    public void setConsumer(XMLConsumer consumer)
        throws PipelineException {
        this.consumer = consumer;
    }


    /**  Recycles the instance */
    public void recycle() {
        input = null;
        consumer = null;
        transformer = null;
    }


    /**
     *  Gets the id
     *
     *@return    The id value
     */
     public String getId() {
        return id;   
     }
    
    /**
     *  Sets the id
     *
     *@param  id  The unique id
     */
     public void setId(String id) {
         this.id = id;
     }

    /**
     *  Generates SAX events from the DOM node
     *
     *@exception  PipelineException  If anything goes wrong
     */
    public void generate()
        throws PipelineException {
        try {
            DOMSource source = new DOMSource(input);
            SAXResult result = new SAXResult(consumer);
            result.setLexicalHandler(consumer);

            transformer.transform(source, result);
        } catch (Exception ex) {
            throw new PipelineException(ex);
        }

    }

}

